package org.jeecg.modules.kuner.userrec.service.impl;


import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;

import lombok.extern.slf4j.Slf4j;
import org.jeecg.common.constant.CommonConstant;
import org.jeecg.common.exception.JeecgBootException;

import org.jeecg.common.util.CollectionsUtil;
import org.jeecg.common.util.PlanifoliaRedisUtil;
import org.jeecg.common.util.Strings;
import org.jeecg.modules.kuner.userpointstatement.service.ISdUserPointStatementService;
import org.jeecg.modules.kuner.userrec.entity.UserRecShip;
import org.jeecg.modules.kuner.userrec.mapper.UserRecShipMapper;
import org.jeecg.modules.kuner.userrec.service.IUserRecShipService;
import org.jeecg.modules.kuner.userrec.vo.RecommendUserVO;
import org.jeecg.modules.system.entity.SysUser;
import org.jeecg.modules.system.service.ISysUserService;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @Description: 推荐关系
 * @Author: jeecg-boot
 * @Date: 2024-08-28
 * @Version: V1.0
 */
@Service
@Slf4j
public class UserRecShipServiceImpl extends ServiceImpl<UserRecShipMapper, UserRecShip> implements IUserRecShipService {


    @Resource
    private ISysUserService sysUserService;
    @Resource
    private PlanifoliaRedisUtil planifoliaRedisUtil;


    /**
     * 根据userId获取到推荐人数
     *
     * @param id 会员ID
     * @return 查询到的推荐人数
     */
    @Override
    public long getMemberRecCount(String id) {
        return count(new LambdaQueryWrapper<UserRecShip>().eq(UserRecShip::getMasterId, id));
    }

    /**
     * 绑定推荐关系
     *
     * @param userId   会员ID
     * @param masterId 推荐人ID
     */
    @Override
    public void bindRecommendShip(String userId, String masterId) {
        //判断当前用户是扫码注册还是自行注册
        SysUser userInfo = Optional.ofNullable(sysUserService.getById(userId)).orElseThrow(() -> new JeecgBootException("无法找到被绑定人信息"));
        SysUser masterInfo = Optional.ofNullable(sysUserService.getById(masterId)).orElseThrow(() -> new JeecgBootException("无法找到推荐人信息"));
        if (Strings.equals(userId, masterId))
            throw new JeecgBootException("无法自我绑定！");
        UserRecShip userRecShip = getUserMasterInfo(userId);
        if (userRecShip != null) {
            log.error("用户 ：{}已经绑定过推荐人：{}", userId, userRecShip.getMasterId());
            throw new JeecgBootException("您已绑定过其他的推荐人信息！");
        }
        // 保存推荐关系
        userRecShip = new UserRecShip();
        userRecShip.setUserId(userInfo.getId()).setMasterId(masterInfo.getId());
        save(userRecShip);
        planifoliaRedisUtil.hdel(CommonConstant.USER_RECOMMEND, userId);
        planifoliaRedisUtil.hdel(CommonConstant.USER_RECOMMEND, masterId);
        log.info("用户 ：{}绑定推荐者：{}成功！", userId, masterId);
    }


    /**
     * 根据自己的会员id查询出自己的推荐关系
     *
     * @param userId 会员id
     * @return 上级的推荐关系
     */
    @Override
    public UserRecShip getUserMasterInfo(String userId) {
        try {
            return getOne(new LambdaQueryWrapper<UserRecShip>().eq(UserRecShip::getUserId, userId));
        } catch (Exception e) {
            log.error("错误的推荐关系，用户信息{}。", userId);
            throw new JeecgBootException(String.format("错误的用户:{%s}推荐关系，请联系系统管理员！", userId));
        }
    }

    /**
     * 我的推荐用户信息
     *
     * @return 查询到的结果
     */
    @Override
    public RecommendUserVO myRecommend(String userId) {
        return planifoliaRedisUtil.executeHGetWithLock(CommonConstant.USER_RECOMMEND, userId, () -> getRecommendMemberByMasterId(userId));
    }


    /**
     * 根据推荐人id查询出直推与间推的信息
     *
     * @param userId 推荐人信息
     * @return 查询到的推荐人信息
     */
    private RecommendUserVO getRecommendMemberByMasterId(String userId) {
        List<UserRecShip> allMemberShip = this.getBaseMapper().selectUserRecShip();
        // 处理查询出所有直推的信息
        List<UserRecShip> firstRec = allMemberShip.stream().filter(memberShip -> Strings.equals(userId, memberShip.getMasterId())).collect(Collectors.toList());
        if (CollectionsUtil.isEmpty(firstRec)) {
            return null;
        }
        RecommendUserVO recommendMemberVO = new RecommendUserVO();
        return recommendMemberVO.setFirstRec(firstRec);
    }


}
